package com.shelpe.services.lexicon.service.central;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.shelpe.services.lexicon.entity.KeywordRecommend;

import lombok.Getter;
import lombok.Setter;

@Service
public class FrequencyCentralWordExtractor implements CentralWordExtractor {

	@Override
	public List<KeywordRecommend> extract(List<KeywordRecommend> recommends) {
		Map<String, WordCount> maps = new HashMap<String, WordCount>();
		List<WordCount> counts = new ArrayList<WordCount>();
		for(KeywordRecommend kr:recommends){
			List<WordCount> wcs = this.calc(kr.getWord());
			for(WordCount wc: wcs){
				WordCount found = maps.get(wc.getWord());
				if(found != null){
					found.count = found.count + wc.count;
				}else{
					maps.put(wc.getWord(), wc);
					counts.add(wc);
				}
			}
		}
		Collections.sort(counts);
		
		List<KeywordRecommend> found = new ArrayList<KeywordRecommend>();
		int max = 0;
		for(WordCount wc:counts){
			if(max == 0 || max == wc.count){
				max = wc.count;
				found.addAll(this.findByContainWord(recommends, wc.word));
			}else{
				break;
			}
		}
		
		return found;
	}
	
	private List<KeywordRecommend> findByContainWord(List<KeywordRecommend> recommends, String word){
		List<KeywordRecommend> found = new ArrayList<KeywordRecommend>();
		for(KeywordRecommend kr:recommends){
			if(kr.getWord().contains(word)){
				found.add(kr);
			}
		}
		return found;
	}

	@Setter
	@Getter
	private static class WordCount implements Comparable<WordCount>{ 
        private int count;
        private String word;
        public WordCount(String word, int count){ 
            this.count = count; 
            this.word = word;
        }
		@Override
		public int compareTo(WordCount o) {
			return o.getCount() - this.count;
		}
		@Override
		public int hashCode() {
			return this.word.hashCode();
		}
		@Override
		public boolean equals(Object obj) {
			WordCount that = (WordCount) obj;
			return this.word.equals(that.word);
		} 
		
		
    } 

	private List<WordCount> calc(String word){
		List<WordCount> counts = new ArrayList<WordCount>();
		
		StringBuffer buffer = new StringBuffer(word);
		for(int index = 0; index < buffer.length(); index = index +1){
			String w = buffer.substring(index, index+1);
			WordCount wc = new WordCount(w, 1);
			counts.add(wc);
		}
		
		return counts;
	}

}
